﻿using System;
using System.Net;
using System.Threading;
using System.Linq;
using System.Text;
using VNet.VisiSuite.Common.Logger;

// Started with code from https://codehosting.net/blog/BlogEngine/post/Simple-C-Web-Server.aspx [MIT license]

namespace VNet.VisiSuite.VisiBoard.WebServer
{
    public class SimpleWebServer
    {

        public delegate byte[] ResponderMethod(HttpListenerRequest requet, out string mime_type, out bool cache);
        private readonly HttpListener _listener = new HttpListener();

        public readonly ResponderMethod _responderMethod;

        public SimpleWebServer(string[] prefixes, ResponderMethod method)
        {
            if (!HttpListener.IsSupported)
                throw new NotSupportedException(
                    "Needs Windows XP SP2, Server 2003 or later.");
 
            // URI prefixes are required, for example 
            // "http://localhost:8080/index/".
            if (prefixes == null || prefixes.Length == 0)
                throw new ArgumentException("prefixes");
 
            // A responder method is required
            if (method == null)
                throw new ArgumentException("method");
 
            foreach (string s in prefixes)
                _listener.Prefixes.Add(s);
 
            _responderMethod = method;
            _listener.Start();
        }
 
        public void run()
        {
            ThreadPool.QueueUserWorkItem((o) =>
            {
                FileLog.Error("Webserver running...");
                try
                {
                    while (_listener.IsListening)
                    {
                        ThreadPool.QueueUserWorkItem((c) =>
                        {
                            var ctx = c as HttpListenerContext;
                            try
                            {
                                string mime_type;
                                bool cache = false;
                                byte[] buf = _responderMethod(ctx.Request, out mime_type, out cache);
                                ctx.Response.ContentType = mime_type;
                                if (!cache)
                                    ctx.Response.AddHeader("Cache-Control", "private, max-age=0, no-cache");
                                ctx.Response.ContentLength64 = buf.Length;
                                ctx.Response.OutputStream.Write(buf, 0, buf.Length);
                            }
                            catch (Exception ex)
                            {
                                FileLog.Error("Listener failed - ", ex);
                            }
                            finally
                            {
                                // always close the stream
                                ctx.Response.OutputStream.Close();
                            }
                        }, _listener.GetContext());
                    }
                    FileLog.Error("Done listening.");
                }
                catch (Exception ex)
                {
                    FileLog.Error("Run() - ", ex);
                }

            });
        }
 
        public void stop()
        {
            _listener.Stop();
            _listener.Close();
        }
    }
}